//using System;
//using System.Collections.Generic;
//using System.Text;
//using System.Windows.Forms;

//using Weazel.Gezel.Model;
//using Weazel.Gezel.Model.Errors;

//using Weazel.Badger;
//using Weazel.Badger.ErrorHandling;
//using Weazel.Badger.Vhdl.LibraryFiles;


//namespace Weazel.Toad.Application.Actions
//{
//  public class SynthesizeAsOpbSlaveAction
//    : ActionBase
//  {
//    private class OpbIpBlockParameters
//    {
//      public uint BaseAddress;
//      public uint HighAddress;
//      public uint InterruptCount;
//      public uint RegisterCount;
//    }

//    public SynthesizeAsOpbSlaveAction() 
//    {
//      Enabled = false;

//      Application.Instance.SelectedItemChanged += 
//        new EventHandler<SelectedItemChangedEventArgs>(Instance_SelectedItemChanged);
//    }

//    public override void Execute(object sender, EventArgs e)
//    {
//      if (!(Application.Instance.SelectedItem is Items.GezelTextFile))
//        return;

//      Items.GezelTextFile file = 
//        Application.Instance.SelectedItem as Items.GezelTextFile;

//      List<VerificationError> verificationErrors = new List<VerificationError>();
//      List<VerificationWarning> verificationWarnings = new List<VerificationWarning>();
//      List<ParseError> parseErrors = new List<ParseError>();

//      Model model = 
//        file.ParseAndVerifyModel(
//          ref parseErrors,
//          ref verificationErrors,
//          ref verificationWarnings
//        );

//      if (model == null)
//      {
//        // exception occured during parsing the verification
//        MessageBox.Show("Failed to parse and verify model", "Error");
//        return;
//      }

//      if (parseErrors.Count > 0 || verificationErrors.Count > 0)
//      {
//        MessageBox.Show("Model contains errors - correct them and try again", "Error");
//        return;
//      }

//      if (verificationWarnings.Count > 0)
//      {
//        DialogResult result = 
//          MessageBox.Show("Model contains verification warnings - continue?", "Warning", MessageBoxButtons.YesNo);

//        if (result != DialogResult.Yes)
//          return;
//      }

//      // extract list of datapaths from the model
//      List<string> datapaths = new List<string>();

//      foreach (string key in model.Datapaths.Keys)
//        datapaths.Add(key);

//      // extract list of ip-blocks fromt the model
//      List<string> ipBlocks = new List<string>();

//      foreach (string key in model.IPBlocks.Keys)
//        ipBlocks.Add(key);

//      Forms.MicroblazeOpbSynthesisForm form =
//        new Weazel.Toad.Application.Forms.MicroblazeOpbSynthesisForm();

//      // only set the directory if the gezel file has been saved
//      if (file.Filename != null)
//      {
//        System.IO.FileInfo f = new System.IO.FileInfo(file.Filename);
//        form.Directory = f.DirectoryName;
//      }

//      form.Datapaths = datapaths;
//      form.IpBlocks = ipBlocks;

//      // use the display name minus the ".fdl"
//      form.IpifName = file.DisplayName.Substring(0, file.DisplayName.Length - 4);

//      if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
//      {
//        IPBlock opbIpBlock = model.IPBlocks[form.SelectedIpBlock];

//        // check the type of the ip-block
//        if (!(opbIpBlock.IpType == "opbipifslave"))
//        {
//          string message =
//            string.Format("The ip-block '{0}' is not of type 'opbipifslave'", form.SelectedIpBlock);

//          MessageBox.Show(message);
//          return;
//        }

//        // check that all the parameters are given
//        OpbIpBlockParameters parameters = checkAndProcessIpBlockParameters(opbIpBlock.IpParameters);

//        if (parameters == null)
//          return;

//        Weazel.Badger.Configuration configuration =
//          new Weazel.Badger.Configuration();

//        ConversionContext context =
//          new ConversionContext(model, configuration);

//        // convert but dont write files to disk
//        context.Convert(false);

//        // construct list of dependency files
//        List<string> dependencies = model.GetDependencyList(form.SelectedDatapath);
//        List<string> files = new List<string>();
//        foreach (string s in dependencies)
//          files.Add(s);

//        // add libraries
//        List<OpbIpifCreatorData.Library> libraries = new List<OpbIpifCreatorData.Library>();
//        foreach (Weazel.Badger.Vhdl.LibraryFiles.Libraries library in context.Libraries)
//        {         
//          OpbIpifCreatorData.Library l = new OpbIpifCreatorData.Library();

//          l.LibraryFileName = LibraryFiles.GetLibraryFileName(library);
//          l.LibraryName = LibraryFiles.GetLibraryName(library);

//          // remove the ".vhd" from the file name
//          l.LibraryFileName = 
//            l.LibraryFileName.Substring(0, l.LibraryFileName.Length - 4);

//          libraries.Add(l);
//        }

//        OpbIpifCreatorData data = new OpbIpifCreatorData(
//          form.IpifName,
//          form.MajorVersion,
//          form.MinorVersion,
//          form.Revision,
//          32,
//          (int) parameters.RegisterCount,
//          (int) parameters.InterruptCount,
//          files,
//          libraries,
//          form.Directory
//        );

//        OpbIpifCreator opbIpIfCreator = new OpbIpifCreator();
//        opbIpIfCreator.Create(data);

//        try
//        {
//          // manually output the files in the hdl/vhdl folder
//          foreach (Weazel.Badger.Vhdl.DesignFile designFile in context.SourceFiles)
//            if (dependencies.Contains(designFile.FileName.Substring(0, designFile.FileName.Length - 4)))
//              designFile.Write(data.VhdlDirectory);

//          foreach (Weazel.Badger.Vhdl.LibraryFiles.Libraries library in context.Libraries)
//            Weazel.Badger.Vhdl.LibraryFiles.LibraryFiles.OuputLibraryFile(library, data.VhdlDirectory);
//        }
//        catch (System.IO.IOException ex)
//        {
//          // the above code may fail - mostlikely because another process has a file lock
//          // on a previously generated file with the same name and location ..

//          string message = string.Format("Unable to write files to disk: {0}", ex.Message);
//          MessageBox.Show(message);
//          return;
//        }
//      }
//    }



//    private OpbIpBlockParameters checkAndProcessIpBlockParameters(List<string> parameters)
//    {
//      OpbIpBlockParameters result = new OpbIpBlockParameters();

//      bool 
//        interruptCountFound = false, 
//        lowAddressFound = false, 
//        highAddressFound = false, 
//        registerCountFound = false;

//      foreach (string name in parameters)
//      {
//        string field = name.Substring(0, name.IndexOf('='));
//        string value = name.Substring(name.IndexOf('=') + 1);

//        try
//        {
//          if (field == "interrupts")
//          {
//            result.InterruptCount = uint.Parse(value);
//            interruptCountFound = true;
//          }
//          else if (field == "low_address")
//          {
//            result.BaseAddress = Convert.ToUInt32(value, 16);
//            lowAddressFound = true;
//          }
//          else if (field == "high_address")
//          {
//            result.HighAddress = Convert.ToUInt32(value, 16);
//            highAddressFound = true;
//          }
//          else if (field == "registers")
//          {
//            result.RegisterCount = uint.Parse(value);
//            registerCountFound = true;
//          }
//        }
//        catch (Exception)
//        {
//          string message = 
//            string.Format("Failed to parse value for IP parameter '{0}'", field);

//          MessageBox.Show(message, "Error");
//          return null;
//        }
//      }

//      bool ok =
//        interruptCountFound && 
//        lowAddressFound && 
//        highAddressFound && 
//        registerCountFound;

//      if (!ok)
//      {
//        string message =
//          "Missing IP parameter";

//        MessageBox.Show(message, "Error");

//        return null;
//      }

//      return result;
//    }

//    void Instance_SelectedItemChanged(object sender, SelectedItemChangedEventArgs e)
//    {
//      if (e.SelectedItem is Items.GezelTextFile)
//      {
//        Enabled = true;
//      }
//      else
//      {
//        Enabled = false;
//      }
//    }
//  }
//}
